#ifndef CLIENTE_H
#define	CLIENTE_H

#include <string>
#include <cstdlib>
#include <sstream>
#include <cstdio>
#include <iostream>
#include <ostream>
#include <vector>
#include "Conexion.h"
#include "Excepcion.h"
#include "IMensajero.h"
#include "IManejadorConexionEvento.h"
#include "Posicion.h"
#include "Partida.h"
#include "Jugador.h"
#include "Excepcion.h"
#include "ProtocoloConstantes.h"
#include "MotorJuegoServicioConstantes.h"
#include "MundoServicioConstantes.h"
#include "PartidaServicioConstantes.h"
#include "Mutex.h"

using namespace std;
using namespace TP;
using namespace TP::Servicios;
using namespace TP::Comunicacion;
using namespace TP::Comunicacion::Eventos;
using namespace TP::Juego;
using namespace TP::Juego::Arena;
using namespace TP::Juego::Arena::Actores;
using namespace TP::Juego::Motorizacion::Fisica;

namespace TP { namespace Comunicacion { 

    class Cliente {  
    public:   
        Cliente(Jugador* pJugador, Conexion* pConexion, std::ostream& pLog);
        
        Cliente(Jugador* pJugador, const string& pIp, const string& pPuerto, std::ostream& pLog);

        virtual ~Cliente();

        void Iniciar() throw (Excepcion&);
        
        void Finalizar() throw (Excepcion&);
        
        Partida* crearPartida (const string& pNombreMundo, unsigned int pIdNivel, const string& pNombrePartida) throw (Excepcion&);

        Partida* unirAPartida (const string& pNombrePartida) throw (Excepcion&);
        
        void abandonarPartida () throw (Excepcion&);
        
        vector<string> listarPartidas () throw (Excepcion&);
        
        vector<string> listarMundos() throw (Excepcion&);
        
        vector<string> listarNiveles(const string &nombreMundo) throw (Excepcion&);       
        
        Partida* getPartida() throw (Excepcion&);
        
        void atacar (Posicion* pPosicion) throw (Excepcion&);
    
    private:
        void ejecutarComando (const string& pComando) throw (Excepcion&);      
        void ejecutarComando (const string& pComando, vector <string>& pRespuesta) throw (Excepcion&);      
        void enviarMensaje (const string& pMensaje) throw (Excepcion&);      
        void esperarRespuesta (string& pMensaje) throw (Excepcion&);       
        void parsearLista(vector<string> &partidas, const string & pDescriptor);
        
        std::ostream& _log;
        Conexion* _conexion;
        Partida* _partida;
        Jugador* _jugador;
        vector<string> _listaPartidas;
        vector<string> _listaMundos;
        vector<string> _listaNiveles;      
        Mutex _mutex;      
    };
}}

#endif	/* CLIENTE_H */

